﻿using System;
using Microsoft.Xna.Framework;

namespace OmegaEngine
{
    public class Component
    {
        // The GameScreen Object that owns this component
        public GameScreen Parent;

        // Whether or not this component has been initialized
        public bool Initialized = false;

        // Whether or not the GameScreen that owns the component should draw it
        public bool Visible = true;

        // Draw order. Lower values draw first
        int drawOrder = 1;
        
        // The name of the Component
        public string Name = "";

        // This overloaded constructor allows us to specify the parent
        public Component(GameScreen Parent)
        {
            InitializeComponent(Parent);
        }

        // This overload allws will set the parent to the default GameScreen
        public Component()
        {
            InitializeComponent(Engine.DefaultScreen);
        }

        // Draw order changed event
        public event ComponentDrawOrderChangedEventHandler DrawOrderChanged;

        // Pulic draw order. If the value is changed, we fire the draw order change event
        public int DrawOrder
        {
            get { return drawOrder; }
            set
            {
                // Save a copy of the old value and set the new one
                int last = drawOrder;
                drawOrder = value;

                // Fire DrawOrderChanged
                if (DrawOrderChanged != null)
                    DrawOrderChanged(this, new ComponentDrawOrderChangedEventArgs(this, last, this.Parent.Components));
            }
        }

        // This is called by the constructor to inialize the component. This allows us
        // to onlyhave to override this method instead of both constructors
        protected virtual void InitializeComponent(GameScreen Parent)
        {
            // Check if the engine has been initalized before setting up the component,
            // or the Engine will crash when the component tries to add itself to the list.
            if(!Engine.IsInitialized)
                throw new Exception("Engine must be inialized with \"SetupEngine()\" before components can be inialized");

            Parent.AddComponent(this);
            Initialized = true;
        }

        // Updates the component - This is called by the owner
        public virtual void Update()
        {

        }

        // Draws the component - This is called by the owner
        public virtual void Draw()
        {

        }

        // Unregister the component with its parent
        public virtual void DisableComponent()
        {
            Parent.Components.Remove(this);
        }
    }

    // Event arguments for draw order change on a component
    public class ComponentDrawOrderChangedEventArgs : EventArgs
    {
        // Component that was modified
        public Component Component;

        // The old draw order
        public int LastDrawOrder;

        // The collection that owns the component
        public ComponentCollection ParentCollection;

        public ComponentDrawOrderChangedEventArgs(Component Component,
            int LastDrawOrder, ComponentCollection ParentCollection)
        {
            this.Component = Component;
            this.LastDrawOrder = LastDrawOrder;
            this.ParentCollection = ParentCollection;
        }
    }

    // Event handler for draw order change on a component
    public delegate void ComponentDrawOrderChangedEventHandler(object sender, ComponentDrawOrderChangedEventArgs e);
}